<?php

/**
 * SAAS关务统一下单接口
 * @author chenshubo
 */
namespace App\Service\VendorClient\ShopGwApi;
use App\Service\Code\Normal;
use App\Service\BaseService;
use Service\AppService\IdService;
use App\Service\OrderService\OrderInterfaceService\OrderPay;
use App\Service\TaskServer\TaskWorker;
use function GuzzleHttp\json_encode;

class ShopGwApiClient extends BaseService
{
    /**
     * 接口路由定义
     * @var array
     */
    protected $routers = [
        'queryGoodsList'            => '/customserver/initcommoditydata',
        'createOrder'               => '/customserver/placeorder',
        'payOrder'                  => '/customserver/placeorderconfirm',
        'cancelOrder'               => '/customserver/placeorderconfirm',
        'OrderRevoke'               => '/customserver/invtrrevoke',
        'queryOrderDeclare'         => '/customserver/getinvtmessage',
        'queryOrderDeclareContent'  => '/customserver/declare/action/query/type/orderDeclare',
        'queryLogisticDeclare'      => '/customserver/declare/action/query/type/logisticDeclare',
        'queryInventoryDeclare'     => '/customserver/declare/action/query/type/InvtDeclareData',
        'queryInventoryCancel'      => '/customserver/declare/action/query/type/invtCancelDeclare',
        'ReceiveDeclareResult'      => '/customserver/declare/action/query/type/ReceiveDeclareResult',
        'PddRepushDeclareModel'     => '/customserver/declare/action/query/type/PddRepushDeclareModel',
        'PddGetOrderResponse'       => '/customserver/ManualFishingOrderReceive',
    ];
    
    protected $config;
    /**
     * 初始化配置 
     * @param array $apiBody
     */
    public function __construct($apiBody=[])
    {
        $this->config = $apiBody;
    }
    
    /**
     * 创建订单
     * @param array $params
     * @return mixed
     */
    public function createOrder( $param = [] )
    {
        $supplierGoods  = $param['supplierGoodsInfo'];
        //下单信息
        $orderInfo      = $param['order'];
        //原始商品数据组
        $goodsList      = $supplierGoods['goodsList'];
        //下单商品
        $orderGoods     = $param['order']['goods'];
        
        //额外库存数据
        $stockBatchRowList = $supplierGoods['stockBatchRowList']??[];
        
        //处理收获地址问题
        $receiveAddress = implode("", [
            $orderInfo['province'],
            " ",
            $orderInfo['city'],
            " ",
            $orderInfo['district'],
            "n",
            $orderInfo['receiveAddress'],
        ]);
        
        //获取下单商品信息
        $palceOrderGoods = [];
        $totalGoodsMoney = $freight = 0;
        foreach ($orderGoods as $item )
        {
            //商品价格 = 商品价格 + 商品税费
            $goodsMoney     = bcadd((string)$item['goodsPrice'], (string)($item['goodsTax']??0),2);
            //供应商商品信息
            $supplierGoods  = $goodsList[$item['goodsSku']];
            //上游SKU
            $commoditySKU   = $supplierGoods['supplierSKUCode'];
            //下单数量
            $goodsSaleCount = bcmul((string)$item['goodsNum'],(string)$item['goodsSpecNum']);
            //规格数量
            $goodsSpecNum   = $item['goodsSpecNum'];
            //单个商品价格
            $singlePrice    = bcdiv((string)$goodsMoney,(string)$goodsSpecNum,2);
            
            $BatchID  = (string)($supplierGoods['batchID']??'');
            $BatchID  = isset($stockBatchRowList[$commoditySKU]) ? (string) $stockBatchRowList[$commoditySKU] : $BatchID ; 
			
			$extends_orderType  = $orderInfo['extends']['orderType'] ?? '';
			
            //开始进行订单申报商品
            $goods=[
                'validityPeriod'        => !empty($item['startExpDate']) ? $item['startExpDate'] : null,//下游传上来的效期(产品说的是效期是他们自己维护的 ,跟我们没得关系,我们也不敢多问 )
                'batchID'               => $extends_orderType == 'jd' ? '' : $BatchID,
                'commodityCount'        => (string)$goodsSaleCount,
                'commoditySKU'          => $commoditySKU,
                'commodityRealPrice'    => (float)$singlePrice,
                'commodityName'         => $item['commodityName']??''//商品名称
            ];
            if (isset($item['gIndex'])){
                $goods['index']=(int)$item['gIndex'];
            }
            $palceOrderGoods[] = $goods;
            $totalGoodsMoney += (float)(bcmul((string)$goodsSaleCount, (string)$singlePrice,2));
            $freight += (float) $item['freight'];
        }
        
        //总运费(运费 +运费税)
        $delivery       = bcadd((string)$freight, 0.00,2);
        //下单总金额(商品总金额 + 总运费)
        $totalMoney     = bcadd((string)$totalGoodsMoney,(string)$delivery,2);

        //是否支付单申报
        $isDeclarePay   = (
            (isset($orderInfo['isPayDeclare']) && $orderInfo['isPayDeclare'] == 1) ||
            (isset($orderInfo['order_type']) && $orderInfo['order_type'] == 1)
            ) ? true : false ;
        
        //是否订单申报
        $isOrderDeclare = (isset($orderInfo['isOrderDeclare']) && $orderInfo['isOrderDeclare'] == 1) ? true : false ;
        
        //拼多多京东扩展参数
        $extends_orderType  = $orderInfo['extends']['orderType'] ?? '';
        $extends_mall_id    = $orderInfo['extends']['mall_id'] ?? '';
        $isCallApi          = $orderInfo['extends']['isCallApi'] ?? false;
        $jdOrderType        = $orderInfo['extends']['jdOrderType'] ?? 0;
        $extends_remark     = $orderInfo['orderRemarks'] ?? '';
        
        //是否是京东加密订单
        $isEncryptOrder     = isset($orderInfo['extends']['isEncryptOrder']) && $orderInfo['extends']['isEncryptOrder'] == 1 ? 1 : 0;//是否是京东加密订单
        
        //优惠金额
        $discountMoney      = $orderInfo['discountMoney'] ?? 0.00;
        $discountMoney      = $discountMoney >= 0 ? $discountMoney : ( 0 - $discountMoney);
        $customerCode       = $extends_orderType == 'sanxidatong' ? $this->config['customercode'] : $supplierGoods['warehouseAccount'] ;
        
        //是否保税自提订单
        $is_bbc_self_take   = $param['binfo']['is_bbc_self_take'] ?? 0;
        $order_type         = $orderInfo['order_type'] ?? 0 ;
        
        //组装推送上游数据
        $requestParam = [
            'method'    => 'createOrder',
            'isCallApi' => $isCallApi,
            'data'      => [
                'placeOrderInfo' => [
                    'SingleChannel'         => $orderInfo['orderSource'],
                    'customerCode'          => $customerCode,  //货主编号
                    'CompanyOrderCode'      => $orderInfo['supplier_dsn'],      //S2B 子单号
                    'ShopOrderCode'         => $orderInfo['orderSn'],          // 下游订单号
                    'receiverName'          => $orderInfo['receiveName'],
                    'receiverPhone'         => $orderInfo['recveivePhone'],
                    'province'              => $orderInfo['province'],
                    'city'                  => $orderInfo['city'],
                    'district'              => $orderInfo['district'],
                    'ReceiverAddress'       => $orderInfo['receiveAddress'],
                    'paymentName'           => $orderInfo['buyerRealName'],
                    'paymentPhone'          => $orderInfo['buyerPhone'],
                    'paymentCart'           => $orderInfo['buyerIdCard'],
                    'payment'               => $isDeclarePay ? 99 : 1 ,
                    'isDeclarePay'          => $isDeclarePay , //支付单是否已申报（true -已申报，false-未申报）
                    'isOrderDeclare'        => $isOrderDeclare,//订单是否已申报（true -已申报，false-未申报）
                    'totalPrice'            => (float)$totalMoney,
                    'freight'               => ($extends_orderType=='jd')?(float)$freight:(float)$delivery,
                    'taxPrice'              => ($extends_orderType=='jd')?(float)$orderInfo['freightTax']:0,
                    'DiscountPrice'         => (float)$discountMoney,
                    'palceOrderCommoditys'  => $palceOrderGoods,
                    'payerFlowNo'           => '',
                    'PayCommanyName'        => '',
                    'PayCommanyCode'        => '',
                    'deliveryUrl'           => config('api.yc_sys.deliveryUrl'),
                    'cancelUrl'             => config('api.yc_sys.cancelUrl'),
                    'orderType'             => $this->getOrderTypeToGw($order_type,$is_bbc_self_take),
                ],
                'extendedParameters' => [
                    'isEncryptOrder'    => $isEncryptOrder,//京东加密（1-是，0-不是）
                    'jdOrderType'       => (string)$jdOrderType,//京东独立站
                    'orderType'         => (string)$extends_orderType,
                    'shop'              => (string)$extends_mall_id,
                    'remark'            => (string)$extends_remark,
                ]
            ],
        ];
        return $this->execute($requestParam);
    }

    public function getOrderTypeToGw($order_type,$is_bbc_self_take)
    {
        if (in_array($order_type,OrderPay::YW_ORDER_TYPE_ARR)){
            return 9;
        }
        return $order_type;
    }

    /**
     * 取消订单
     * @param array $params
     * @return mixed
     */
    public function cancelOrder( $params = [] )
    {
        $orderSupplier = $params['supplierOrder'];
        $order         = $params['order'];
        $requestParam = [
            'method'    => 'cancelOrder',
            'data'      => [
                'placeOrderConfirmInfo' => [
                    'CompanyOrderCode'  => $orderSupplier['supplier_dsn'],
                    'isConfirm'         => false,
                    'payerFlowNo'       => '',
                    'payCommanyName'    => '',
                    'payCommanyCode'    => '',
                ]
            ],
        ];
        return $this->execute($requestParam);
    }
    
    /**
     * 订单支付
     * @param array $params
     * @return mixed
     */
    public function payOrder( $params = [] )
    {
        $orderSupplier      = $params['supplierOrder'];
        $order              = $params['order'];
        $supplier_dsn       = $orderSupplier['supplier_dsn'];
        
        //支付拓展信息
        $apply_extends      = @json_decode($orderSupplier['apply_extends'],true);
        $apply_extends      = empty($apply_extends) ? $order : $apply_extends;
        
        //多多海关申报订单好字段
        $innerTransactionId = $order['inner_transaction_id']??'';
        $innerTransactionId = $innerTransactionId ? $innerTransactionId : ($apply_extends['innerTransactionId']??'');
        $innerTransactionId = $innerTransactionId ? $innerTransactionId : $supplier_dsn;
        
        //京东订单字段
        $EBCCode        = $order['EBCCode'] ?? ($apply_extends['EBCCode'] ?? '');
        $expressSn      = $order['expressSn'] ?? ($apply_extends['expressSn'] ?? '');
        $portNo         = $order['PortNo'] ?? ($apply_extends['PortNo'] ?? '');
        $IsTransDeclare = $order['IsTransDeclare'] ?? ($apply_extends['IsTransDeclare'] ?? 0);
        $logisticNo     = $order['logisticNo'] ?? $apply_extends['logisticNo'] ?? '';
        $logisticCode   = $order['logisticCode'] ?? $apply_extends['logisticCode'] ?? '';
        $logisticName   = $order['logisticName'] ?? $apply_extends['logisticName'] ?? '';
        $logisticWayBillContent = $order['logisticWayBillContent'] ?? ($apply_extends['logisticWayBillContent'] ?? '');

        //是否跳过订单申报
        $SkipOrderDelcare       = isset($order['SkipOrderDelcare']) && $order['SkipOrderDelcare'] == true ? true : false;
        //是否跳过运单申报
        $SkipWayBillDeclare     = isset($order['SkipWayBillDeclare']) && $order['SkipWayBillDeclare'] == true ? true : false;
        //是否跳过清单申报
        $SkipInventoryDeclare   = isset($order['SkipInventoryDeclare']) && $order['SkipInventoryDeclare'] == true ? true : false;
        
        $requestParam = [
            'method'    => 'payOrder',
            'data'      => [
                'placeOrderConfirmInfo' => [
                    'CompanyOrderCode'      => $orderSupplier['supplier_dsn'],
                    'isConfirm'             => true,
                    'payerFlowNo'           => (string)$order['paySerial'],
                    'payCommanyName'        => $order['payCommanyName'],
                    'payCommanyCode'        => $order['payCommanyCode'],
                    'EnterpriseCode'        => $order['enterpriseNum'],
                    'EBPName'               => $order['enterpriseName'],
                    'EBCCode'               => $EBCCode,//电商企业编号 (京东使用)
                    'LogisticsCode'         => (string)$expressSn ?? $order['logisticNo'],//物流单号 (京东使用)
                    'PortNo'                => (string)$portNo,//口岸编码 (京东使用)
                    'DeclareOrderSn'        => $innerTransactionId,
                    'SkipOrderDelcare'      => $SkipOrderDelcare,
                    'SkipWayBillDeclare'    => $SkipWayBillDeclare,
                    'SkipInventoryDeclare'  => $SkipInventoryDeclare,
                    'LogisticNo'            => $logisticNo,
                    'LogisticCode'          => $logisticCode,
                    'LogisticName'          => $logisticName,
                    'DataInfo'              => $logisticWayBillContent,
					'IsTransDeclare'        => (int)$IsTransDeclare,
                ]
            ],
        ];
        return $this->execute($requestParam);
    }

    /**
     * 获取订单清关申报报文
     * @param array $param
     */
    public function queryOrderDeclare( $param = [] )
    {
        $supplierOrder      = $param['supplierOrder'];
        $supplier           = $param['supplier'];
        $order_sn           = $supplierOrder['order_sn']; 
        $requestParam = [
            'method'        => 'queryOrderDeclare',
            'return'        => true,
            'uid'           => $order_sn,
            'company_code'  => $supplier['company_code'],
            'data'      => [
                'placeOrderConfirmInfo' => [
                    'CompanyOrderCode'  => $order_sn,
                ]
            ],
        ];
        return $this->execute($requestParam);
    }

    /**
     * 同步通知关务进行撤单
     * @param array $param
     */
    public function OrderRevoke( $param = [] )
    {
        $supplierOrder      = $param['supplierOrder'];
        $supplier           = $param['supplier'];
        $order_sn           = $supplierOrder['order_sn'];
        $requestParam = [
            'method'        => 'OrderRevoke',
            'uid'           => $order_sn,
            'company_code'  => $supplier['company_code'],
            'data'      => [
                'companyOrderCodes' => [
                    'companyOrderCode'  => [
                        $order_sn
                    ],
                ]
            ],
        ];
        return $this->execute($requestParam);
    }
    
    /**
     * 获取关务商品信息
     * @param array $param
     */
    public function queryGoodsList( $param = [] )
    {
        $page = $param['page'] ?? 1;
        $page = $page >= 1 ? $page - 1 : 0;
        $data = [
            'pageCount' => $param['limit'] ?? 10,
            'pageIndex' => $page,
            'condition.customerCode' => $this->config['customercode']
        ];
        if( empty($this->config['baseurl']) ) {
            return Normal::returnCode(Normal::FAIL,"当前仓库参数baseurl未配置");
        }
        $url = $this->config['baseurl'] . $this->config['queryGoodsList'] . "?" . http_build_query($data);
        $parameter = [
            [
                'tag'    => 'shopcustom_queryGoodsList',
                'uid'    => IdService::instance()->getOtherID(),
                'url'    => $url,
                'data'   => $data,
                'method' => 'get',
                'format' => 'json',
                'header' => []
            ]
        ];
        $resTask  = TaskWorker::instance()->addTask($parameter, 'handleDiableTask');
        $resTask  = current($resTask);
        $response = $resTask['response']['result'];
        $result  = @json_decode($response, true);
        if( $resTask['response']['httpCode'] == Normal::SUC ) {
            return Normal::returnCode(Normal::SUC, "获取成功", $result);
        } else {
            $msg = !empty($result) ? ($result['message']??'请求失败') : $resTask['response']['result'] ;
            return Normal::returnCode(Normal::FAIL,$msg);
        }
    }

    /**
     * CURL请求
     * @param $params
     * @return mixed
     */
    public function execute( $param = [] )
    {
        $return        = $param['return'] ?? false;
        $uid           = $param['uid'] ?? false;
        $company_code  = $param['company_code'] ?? false;
        $method        = $param['method'];
        $data          = $param['data'];
        $header = [
            "Content-Type: application/json",
            "Accept:application/json"
        ];
        
        if( empty($this->config['baseurl']) ) {
            return Normal::returnCode(Normal::FAIL,"当前仓库参数baseurl未配置");
        }
        
        $baseUrl  = $this->config['baseurl'];
        if( empty($this->routers[$method]) ) {
            return Normal::returnCode(Normal::FAIL,"当前仓库参数【{$method}】未配置");
        }
        
        $applyUrl = $this->config['baseurl'].$this->routers[$method];
        if( empty($param['data']) ) {
            return Normal::returnCode(Normal::FAIL,"数据不能为空");
        }
        
        $isCallApi = $param['isCallApi'] ?? false;
        
        if( $isCallApi == true || $param['method'] != 'createOrder' )
        {
            $form_data = [
                'tag'           => 'shopcustom_'.$method,
                'uid'           => $uid ? $uid : IdService::instance()->getOtherID(),
                'company_code'  => $company_code,
                'url'           => $applyUrl,
                'data'          => $data,
                'method'        => 'post',
                'format'        => 'json',
                'header'        => [],
            ];
            
            if( $return ) {
                return Normal::returnCode(Normal::SUC,"获取成功",$form_data);
            }
            
            $parameter = [$form_data];
            $resTask = TaskWorker::instance()->addTask($parameter);
            $resTask = current($resTask);
            $result  = @json_decode($resTask['response']['result'],true);
            if( $resTask['response']['httpCode'] == Normal::SUC ) 
            {
                return Normal::returnCode(Normal::SUC,"OK");
            } 
            else
            {
                $msg = $resTask['response']['result'] ? $resTask['response']['result'] : "请求失败";
                return Normal::returnCode(Normal::FAIL,$msg);
            }
        }
        
        return Normal::returnCode(Normal::SUC,"获取成功",[
            'url'       => $applyUrl,
            'data'      => $data,
            'format'    => 'json'
        ]);
    }


    /**
     * 取消订单
     * @param array $params
     * @return mixed
     */
    public function sendOrderResult( $params = [] )
    {
        $requestParam = [
            'method'    => 'PddGetOrderResponse',
            'data'      => $params,
        ];
        return $this->execute($requestParam);
    }
}